﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JGSY.Tasks
{
    public class Lock1
    {
    
        private static readonly object _lockObject = new object();
        private static int _sharedCounter = 0;
        private static int _unsynchronizedCounter = 0;

        public static async Task Lock001()
        {
            Console.WriteLine("开始演示lock关键字的使用...\n");

            // 启动多个线程同时修改共享资源（未同步）
            Console.WriteLine("启动多个线程同时修改未同步的共享资源...");
            Task[] unsynchronizedTasks = new Task[10];
            for (int i = 0; i < 10; i++)
            {
                unsynchronizedTasks[i] = Task.Run(() =>
                {
                    for (int j = 0; j < 1000; j++)
                    {
                        _unsynchronizedCounter++;
                        Thread.Sleep(1); // 模拟一些工作
                    }
                });
            }
            await Task.WhenAll(unsynchronizedTasks);
            Console.WriteLine($"未同步的计数器预期值: 10000，实际值: {_unsynchronizedCounter}");
            Console.WriteLine($"未同步的计数器出现竞态条件，结果不正确！\n");

            // 重置计数器
            _unsynchronizedCounter = 0;

            // 启动多个线程同时修改共享资源（使用lock同步）
            Console.WriteLine("启动多个线程同时修改使用lock同步的共享资源...");
            Task[] synchronizedTasks = new Task[10];
            for (int i = 0; i < 10; i++)
            {
                synchronizedTasks[i] = Task.Run(() =>
                {
                    for (int j = 0; j < 1000; j++)
                    {
                        IncrementCounter();
                        Thread.Sleep(1); // 模拟一些工作
                    }
                });
            }
            await Task.WhenAll(synchronizedTasks);
            Console.WriteLine($"同步的计数器预期值: 10000，实际值: {_sharedCounter}");
            Console.WriteLine($"使用lock同步后，计数器结果正确！\n");

            // 演示lock的嵌套使用
            Console.WriteLine("演示lock的嵌套使用...");
            Task nestedTask = Task.Run(() =>
            {
                lock (_lockObject)
                {
                    Console.WriteLine("第一次获取锁成功");
                    // 可以在同一个线程中再次获取同一个锁
                    lock (_lockObject)
                    {
                        Console.WriteLine("嵌套获取锁成功");
                        // 执行一些操作
                    }
                    Console.WriteLine("释放嵌套锁");
                }
                Console.WriteLine("释放第一次获取的锁\n");
            });
            await nestedTask;

            // 演示死锁情况
            Console.WriteLine("演示死锁情况（将导致程序卡住）...");
            object lockA = new object();
            object lockB = new object();

            Task taskA = Task.Run(() =>
            {
                lock (lockA)
                {
                    Console.WriteLine("TaskA 获取了锁A");
                    Thread.Sleep(100); // 确保TaskB有机会获取锁B
                    Console.WriteLine("TaskA 尝试获取锁B...");
                    lock (lockB)
                    {
                        Console.WriteLine("TaskA 获取了锁B（这行不会被执行）");
                    }
                }
            });

            Task taskB = Task.Run(() =>
            {
                lock (lockB)
                {
                    Console.WriteLine("TaskB 获取了锁B");
                    Thread.Sleep(100); // 确保TaskA有机会获取锁A
                    Console.WriteLine("TaskB 尝试获取锁A...");
                    lock (lockA)
                    {
                        Console.WriteLine("TaskB 获取了锁A（这行不会被执行）");
                    }
                }
            });

            // 等待一段时间，观察死锁
            await Task.Delay(2000);
            Console.WriteLine("检测到死锁 - 两个任务都在等待对方释放锁\n");

            Console.WriteLine("演示完成");
        }

        static void IncrementCounter()
        {
            lock (_lockObject)
            {
                // 只有一个线程可以进入这个代码块
                _sharedCounter++;
            }
        }
    }
}
 
